﻿using Colyseus;
using NetWorkToolkit;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public delegate void RespFunc<T>(T info);

public class MessageResp : IMessageResp
{

    public Dictionary<string, RespFunc<string>> CommandRespHandler = new Dictionary<string, RespFunc<string>>();

    public void RegisterCommandResp()
    {
        CommandRespHandler.Add(CommandMsgId.Test, (str) =>
         {
             SocketIOExample.Instance.ShowCommandLog(str);
         });
    }

    public void onCommandResp(object obj)
    {
        CommondInfo commond = obj as CommondInfo;
        CommandRespHandler[commond.func](commond.param);
    }

    public void onConnectResp(ColyseusClientResult result, object obj)
    {
        Debug.Log("[Server Response] OnConnectResp");

        if (result == ColyseusClientResult.Success)
        {
            Debug.Log("[OnConnectResp Connect Success]");
            // todo something
        }
        else
        {
            Debug.Log("[OnConnectResp Connect Failed]");
            // todo something
        }
    }

    public void onDisconnectResp(object obj)
    {
        Debug.Log("[Server Response] OnDisconnectResp");
        PlayerMe.Instance.ClearPlayerData();

        // todo something
    }

    public void onCreateANetObjectResp(object obj)
    {
        Debug.Log("[Server Response] OnCreateANetObjectResp");

        Entity entity = obj as Entity;
        GameObject go = GameObject.Instantiate(Resources.Load("Player")) as GameObject;
        PlayerNetObject netobject = go.GetComponent<PlayerNetObject>();
        netobject.Init(entity);
        PlayerMe.Instance.AddPlayer(entity.id, netobject);

    }

    public void onDestroyANetObjectResp(object obj)
    {
        NetObjectEntity n = obj as NetObjectEntity;
        PlayerMe.Instance.RemovePlayer(n.entityInfo.id);

        // todo something
    }



    public void onUpdateRoomInfoResp(ColyseusClientResult result, object obj)
    {
        Debug.Log("[Server Response] OnUpdateRoomInfoResp --- " + obj);

        var rooms = (List<CustomRoomAvailable>)obj;

        if (result == ColyseusClientResult.Success)
        {
            // obj is List<CustomRoomAvailable>
            var roomsAvailable = obj as List<CustomRoomAvailable>;

            if (roomsAvailable.Count > 0)
            {
                // 默认加入第一个房间，后续要通过不同的房间标识 加入指定的房间
                CustomRoomAvailable cr = roomsAvailable[0];
                var roomState = JsonUtility.FromJson<RoomState>(cr.metadata.roomInfo);
                // 如果房间未开始（没有调用 SendStartGameMsg)
                if (roomState.state == 0)
                {
                    MessageManager.Instance.SendJoinRoomByIdMsg(roomState.roomID);
                }

                SocketIOExample.Instance.ShowRoomInfo(string.Format("roomName:{0}\n roomId:{1}\n roomPsw{2}\n roomOwner:{3}",
                    roomState.roomName, roomState.roomID, roomState.psw, roomState.owner));
            }
        }
        else
        {
            Debug.LogError("[Server Response] OnUpdateRoomInfoResp Failed !!!");
        }
    }


    // 创建房间回调（ps!:会先收到create a netobj 的回调，随后会收到createRoom的回调）
    public void onCreateRoomResp(ColyseusClientResult result, object obj)
    {
        // obj is Room<State>
        Debug.Log("[Server Response] OnCreateARoomResp --- " + obj);


        if (result == ColyseusClientResult.Success)
        {
            Debug.Log("Join Room Successfully");

            Room<RoomState> room = obj as Room<RoomState>;
            SocketIOExample.Instance.ShowRoomInfo(string.Format("roomName:{0}\n roomId:{1}\n roomPsw{2}\n roomOwner:{3}",
                        room.State.roomName, room.State.roomID, room.State.psw, room.State.owner));
        }
        else
        {
            Debug.Log("Join Room Failed");
        }
    }

    public void onJoinRoomResp(ColyseusClientResult result, object obj)
    {
        // obj is Room<State>
        Debug.Log("[Server Response] OnJoinARoomResp --- " + obj);

        if (result == ColyseusClientResult.Success)
        {
            Debug.Log("Join Room Successfully");
        }
        else
        {
            Debug.Log("Join Room Failed");
        }
    }

    public void onLeaveRoomResp(ColyseusClientResult result, object obj)
    {
        if (result == ColyseusClientResult.Success)
        {
            Debug.Log("LeaveRoom Success");
            PlayerMe.Instance.ClearPlayerData();
        }
        else
        {
            Debug.Log("LeaveRoom Failed");
        }
    }

    public void onStartGameResp(object obj)
    {
        Debug.Log("[Server Response] OnStartGameResp --- " + obj);
    }

    public void onEndGameResp(object obj)
    {
        Debug.Log("[Server Response] onEndGameResp");
    }


    public void onUploadNetSyncModuleInfoResp(object obj)
    {
        Debug.Log("[Server Response] OnUploadNetSyncModuleInfoResp " + obj);
        var m = obj as Message;
        if (m.content.Equals("1"))
        {
            Debug.Log("Upload Success");
        }
        else
        {
            Debug.Log("Upload Failed");
        }
    }

    public void onChangeNetSyncModuleStatusResp(object obj)
    {
        Debug.Log("[onChangeNetSyncModuleStatusResp]");
        SocketIOExample.Instance.ShowBtn("unhold");
    }

    public void onS2CUpdateNetSyncModuleInfoResp(object obj)
    {
        string msg = (obj as Message).content;

        AllNetSyncModulePoseResp table = new AllNetSyncModulePoseResp();
        table = LitJson.JsonMapper.ToObject<AllNetSyncModulePoseResp>(msg);
        foreach (var data in table.datas.Values)
        {
            PlayerMe.Instance.GetNetModuleById(data.moduleid)?.SetDataFromServerData(data.belongid, data.pose);
        }
    }

    public void onChangeOwnershipOfNetModuleResp(object obj)
    {
        var data = LitJson.JsonMapper.ToObject<NetSyncModuleStatus>((obj as Message).content);

        NetSyncModule module = PlayerMe.Instance.GetNetModuleById(data.moduleid);
        if (data.holdon.Equals("True") && data.belongid == ColyseusClient.instance.SessionID)
        {
            module.SetSync(true);
            SocketIOExample.Instance.ShowBtn("unhold");
        }
        else
        {
            module.SetSync(false);
            SocketIOExample.Instance.ShowBtn("hold");
        }
    }
}
